#ifndef QUEST_0_1_META_H
#define QUEST_0_1_META_H

#include "istream"
#include <tr1/unordered_map>
#include "map"
#include "vector"
#define TMP_0 0
#define TMP_1 1
#define TMP_N "temp"

#define IS_SYS_FUNC(_a,_b) { \
    for (string s:sys_func){     \
        if (s == _a)         \
            _b = s;          \
     } \
}

using namespace std;

/**
 * ????
 */
enum Tag {
    ID,
    INT, CHAR, STR, VOID, BOL,//????
    NUM,//????
    ADD, SUB, MUL, DIV, AND, OR,//???
    ASSIGN,//???
    NOT,LEA,
    LPR, RPR,   //()
    LBK, RBK,   //[]
    LBE, RBE,   //{}
    SEM,       //;
    COMMA,     //,
    COL,       //:
    RETURN,
    END,
    ERO,
    TMP,
    UKN,
    STRUCT,
    POINT
};

const static char *tags[] = {
        "id",
        "int", "char", "string", "void", "bol",
        "num",
        "+", "-", "*", "/", "and", "or",
        "=",
        "(", ")",
        "[", "]",
        "{", "}",
        ";",
        ","
        ":",
        "return",
        "!",
        "&",
        "end",
        "struct"
        "."
};

/**
 * ???????
 */
enum Operation {
    OP_LAB,//??
    OP_ENTRY,//????
    OP_EXIT,//????
    OP_DEF,//????
    OP_ASSIGN,//????
    OP_ADD, OP_SUB,
    OP_MUL, OP_DIV,
    OP_NE,
    OP_PUSH_ARG,//????
    OP_CALL,//????
    OP_RETURN,//????
    OP_LEA,
    OP_GETV,
    OP_SETV,
    OP_QUIT,
    OP_POINT
};

const static char *opDesc[] =
        {"label",//
         "entry",
         "exit",
         "define",
         "=",
         "+",//
         "-",//
         "*",//
         "\\",
         "!=",
         "push_arg",
         "call",
         "ret",
         "quit"
        };

/**
 * 系统函数列表
 */
const static map<string, Tag> sys_func = {
        {"print",VOID},
        {"println",VOID},
        {"mem", INT},
        {"mfr", INT},
};

/**
 * ??????
 */
class Token {
public:
    Tag tag;

    Token(Tag t);

    virtual string toString();

    virtual ~ Token();
};

class Id : public Token {
public:
    string name;

    Id(string name);

    virtual string toString();
};

class Num : public Token {
public:
    int value;

    Num(int v);

    virtual string toString();
};

class Str : public Token {
public:
    string str;

    Str(string str);

    virtual string toString();
};

class Char : public Token {
public:
    char ch;

    Char(char ch);

    virtual string toString();
};

class Bol : public Token {
public:
    int bol;

    Bol(int str);

    virtual string toString();

};

class Struct : public Token{
public:
    string type;
    Struct(string type);

    virtual string toString();
};

class Keyword {
public:
    std::tr1::unordered_map<string, Tag> keywords;

    Keyword();

    Tag getTag(string name);
};

class Token;

class Scanner;

class Lexer;

class Var;

class Func;

class Symtab;

class Order;

class OrderGenerator;

#endif //QUEST_0_1_META_H
